package config

import (
	"dragonfly/common"
	"encoding/json"
	"fmt"
	"io"
)

//常量值表示配置里的默认值
const (
	AgentListen      = "0.0.0.0:10001"
	CollectorAddress = "127.0.0.1:10010"
	BufferSize       = 1024 * 1024
	PushCycle        = 60
	PluginDir        = "./plugins"
	WorkerMode       = "passive"

	CollectorListen = "0.0.0.0:10010"
	ManagerListen   = "0.0.0.0:10000"
	PipelineListen  = "0.0.0.0:10020"
	SchedulerListen = "0.0.0.0:10030"
	LogFileLocation = "./logs"
)

//AgentSettings Agent配置
type AgentSettings struct {
	ListenAddress    *string
	CollectorAddress *string
	BufferSize       *int
	PushCycle        *int
	PluginDir        *string
	WorkerMode       *string
}

func (s *AgentSettings) SetDefaults() {
	if s.ListenAddress == nil {
		s.ListenAddress = common.NewString(AgentListen)
	}

	if s.CollectorAddress == nil {
		s.CollectorAddress = common.NewString(CollectorAddress)
	}

	if s.BufferSize == nil {
		s.BufferSize = common.NewInt(BufferSize)
	}

	if s.PushCycle == nil {
		s.PushCycle = common.NewInt(PushCycle)
	}

	if s.PluginDir == nil {
		s.PluginDir = common.NewString(PluginDir)
	}

	if s.WorkerMode == nil {
		s.WorkerMode = common.NewString(WorkerMode)
	}
}

//CollectorSettings Collector配置
type CollectorSettings struct {
	ListenAddress *string
}

func (s *CollectorSettings) SetDefaults() {
	if s.ListenAddress == nil {
		s.ListenAddress = common.NewString(CollectorListen)
	}
}

//ManagerSettings Manager配置
type ManagerSettings struct {
	ListenAddress *string
}

func (s *ManagerSettings) SetDefaults() {
	if s.ListenAddress == nil {
		s.ListenAddress = common.NewString(ManagerListen)
	}
}

//PipelineSettings Pipeline配置
type PipelineSettings struct {
	ListenAddress *string
}

func (s *PipelineSettings) SetDefaults() {
	if s.ListenAddress == nil {
		s.ListenAddress = common.NewString(PipelineListen)
	}
}

//SchedulerSettings Scheduler配置
type SchedulerSettings struct {
	ListenAddress *string
}

func (s *SchedulerSettings) SetDefaults() {
	if s.ListenAddress == nil {
		s.ListenAddress = common.NewString(SchedulerListen)
	}
}

type LogSettings struct {
	EnableConsole bool
	EnableFile    bool
	FileLocation  *string
}

func (s *LogSettings) SetDefaults() {
	s.EnableFile = true

	if s.EnableFile {
		s.FileLocation = common.NewString(LogFileLocation)
	}
}

//Config 全局配置
type Config struct {
	AgentSettings     AgentSettings
	CollectorSettings CollectorSettings
	ManagerSettings   ManagerSettings
	PipelineSettings  PipelineSettings
	SchedulerSettings SchedulerSettings
	LogSettings       LogSettings
}

//ToJSON 配置导出为JSON文件
func (o *Config) ToJSON() string {
	b, _ := json.Marshal(o)
	return string(b)
}

//FromJSON 从JSON文件读取配置
func FromJSON(data io.Reader) *Config {
	var o *Config
	json.NewDecoder(data).Decode(&o)
	return o
}

//SetDefaults 设置配置文件的默认值
func (o *Config) SetDefaults() {
	o.AgentSettings.SetDefaults()
	o.CollectorSettings.SetDefaults()
	o.ManagerSettings.SetDefaults()
	o.PipelineSettings.SetDefaults()
	o.SchedulerSettings.SetDefaults()
	o.LogSettings.SetDefaults()
}

func (c *Config) IsValid() error {
	if err := c.AgentSettings.isValid(); err != nil {
		return err
	}

	if err := c.CollectorSettings.isValid(); err != nil {
		return err
	}

	if err := c.ManagerSettings.isValid(); err != nil {
		return err
	}

	if err := c.PipelineSettings.isValid(); err != nil {
		return err
	}

	if err := c.SchedulerSettings.isValid(); err != nil {
		return err
	}

	return nil
}

func (as *AgentSettings) isValid() error {
	if *as.ListenAddress == "" {
		return fmt.Errorf("Agent ListenAddress cannot be empty")
	}

	if *as.CollectorAddress == "" {
		return fmt.Errorf("Collector Address cannot be empty")
	}

	return nil
}

func (cs *CollectorSettings) isValid() error {
	if *cs.ListenAddress == "" {
		return fmt.Errorf("Collector ListenAddress cannot be empty")
	}

	return nil
}

func (ms *ManagerSettings) isValid() error {
	if *ms.ListenAddress == "" {
		return fmt.Errorf("Manager ListenAddress cannot be empty")
	}

	return nil
}

func (ps *PipelineSettings) isValid() error {
	if *ps.ListenAddress == "" {
		return fmt.Errorf("Pipeline ListenAddress cannot be empty")
	}

	return nil
}

func (ss *SchedulerSettings) isValid() error {
	if *ss.ListenAddress == "" {
		return fmt.Errorf("Scheduler ListenAddress cannot be empty")
	}

	return nil
}
